쿠버네티스 API 구조

개요

쿠버네티스를 다룰 때 kubectl을 이용하여 요청을 날리고는 한다.
또 이때 manifests라고 부르는 yaml 파일을 작성하여 전달을 하는데, 실제로 이것들은 어떤 구조로 이뤄진 것일까?
이 모든 요청들은 실제로 kube-apiserver가 처리하는데, 어떤 방식으로 api서버가 요청을 받아들이고 처리하는지 알아보자.

처음 공부할 때 간과하기 쉬운 게, api 서버를 조작하는 방법에 대한 것이다.
사실 이름만 봐도 알 수 있듯이, api 서버는 말그대로 Web Application Server, 그냥 WAS다.
그렇기 때문에 kubectl로 가하는 모든 조작은 사실 curl 같은 http 요청으로 똑같이 날릴 수가 있다.
개발 언어로 라이브러리를 쓸 때 역시 까보면 결국 api 요청을 날리는 식으로 환원된다는 것을 알 수 있다.

API 서버 접근


먼저 api 서버에 요청을 날릴 때 앞단에서 발생하는 일을 간단하게 본다.
api 서버니까 당연히 특정 주소에 특정 포트(기본 6443) api를 노출하고 있을 텐데, 아무나 접근하고 아무나 명령을 내릴 수 있는 것은 아니다.
이를 위해 api 서버에서 실제 요청이 수행되기 이전에 4가지의 단계가 일어난다.
자세한 내용은 시큐리티#API 서버 보안을 참고하자.

API 구조

모든 요청을 수행하는 것은 kube-apiserver이다.
이 api 서버에는 요청을 어떻게 날려야 하는가?
그냥 WAS일 뿐이라 실제로 curl https://{api server address}/ 이런 식으로 요청을 날리는 것이 가능하다.
근데 이 내부적으로 꽤나 정교하게 만들어진 하위 엔드포인트가 있다.
이를 명확히 하기 위해서 먼저 API 구조에 대해서 알아본다.
일단 가장 큰 범주에서 API는 두 가지로 구분지을 수 있다.

비 리소스(Non-resource)

아래 리소스에 해당하지 않는 모든 엔드포인트는 비 리소스로 간주된다.
클러스터에 대한 조작을 가하지 않거나, 클러스터 내부의 요소들에 대한 상태를 확인하지 않는 요청들이 여기에 해당한다.
대표적으로 /statusz, /healthz 등이 여기에 해당한다.
여기에 해당하는 것은 거의 없으니, 대체로 api라고 한다면 다음의 리소스를 생각해도 무방하다.

리소스(Resource)

리소스는 클러스터를 조작하거나 관리하는데 사용되는 모든 엔드포인트를 말한다.
이 엔드포인트에 각종 HTTP 메서드를 이용해 요청을 날리는 방식으로 api 서버를 조작하게 된다.

POST /api/v1/namespaces/default/pods

가령 default 네임스페이스에 파드를 만든다면, 이런 식으로 요청을 날리면 된다.
(바디에 파드 관련 스펙을 적어줘야 한다.)

개념 정리

명확한 용어 정의를 조금 더 내려보자.

파드로 예를 들어본다면, 파드 자체는 리소스 유형이고, 그 중에서 A 파드 자체를 꼭 집어 말한다면 그것은 리소스이다.
그리고 여러 파드를 한꺼번에 표현한다면 그것은 컬렉션이라 부른다.
근데 뭐.. 실제로는 그냥 파드라 하면 우리는 흔히 리소스를 떠올리고 그렇게 표현하곤 한다.
그렇게 표현해도 어차피 의사소통에 그다지 문제될 게 없으니 개념을 이런 식으로 볼 수 있다고만 알고 있으면 된다.

image.png
참고로 굳이 컬렉션을 명시적으로 개념화한 이유는 이런 것 때문이다.
여러 개의 리소스를 조회하는 요청을 할 때 돌아오는 응답은 큰 kind가 {어떤 리소스}List가 되고, items필드에 어떤 리소스들의 원소가 들어가게 된다.
api 서버가 응답을 하는 값에는 이 컬렉션이 활용되기 때문에 이를 굳이 컬렉션이라고 부른다.

kubectl로 보니 그렇게 안 오던데?

이 말을 듣고 kubectl에 -o json으로 명령을 내려본 당신, 막상 보니 kind가 List로 돼있을 것이다.
kubectl은 여러 개의 리소스 유형을 한꺼번에 조회하는 기능을 지원하기 때문에, 기본적으로 모든 아이템을 받은 후에 이를 List라는 kind로 출력해서 보여준다.
즉 그저 클라이언트 사이드에서만 kind: List가 있을 뿐, 실제로 api 서버에는 그런 kind가 없다는 것에 유의하자.

API 그룹

/api/v1/pods
/apis/apps/v1/deployments
/apis/apps/v1/namespaces/my-namespace/deployments/my-deployment

이 모든 리소스는 저마다 그룹에 속해있는데, 이를 API 그룹이라 부른다.
위의 예시에서, 파드 리소스 유형은 v1이라는 그룹에 속해있는 것이다.
그리고 디플로이먼트 리소스 유형은 apps/v1이라는 그룹에 속한다.
보다시피 API 그룹은 기본적으로 버전 정보와 어떤 역할을 한다던지에 대한 정보가 담긴다.

그럼 /api/apis는 무엇인가?
모든 리소스는 경로 상으로 /api/apis로 시작한다.

코어 그룹이라 하니 여기에만 클러스터에 필수적인 요소들이 들어갈 것만 같지만, 실상은 다르다.
네임드 그룹에는 현재 흔하디 흔하게 쓰이는 디플로이먼트, 인그레스, 컨피그맵 등 다양한 리소스들이 들어가 있다.
그래서 실질적으로 코어 그룹은 처음 쿠버네티스가 만들어질 당시 지정된 리소스들을 규정하는 방식의 잔재라고 보는 게 낫다.

구조 정리

간단하게 도식을 정리하면 이렇게 볼 수 있다. 결론적으로 api 서버에 명령을 내려 클러스터를 조작하고 싶다면, 먼저 대상이 될 리소스를 지정한다. 그리고 그 리소스의 API 그룹과 버전을 앞단 경로로 작성하고, 리소스 유형을 적는다. (만약 특정 네임스페이스로 한정 짓고 싶다면 네임스페이스를 먼저 적어준다.) 그 다음에는 거기에 HTTP 메서드를 이용해서 명령을 내리면 되는 것이다! 이러한 방식을 쉽게 지원하는 명령줄 도구 중 하나가 바로 kubectl인 것이다.

참고로 모든 api를 올인원으로 보고 싶다면 이 문서를 참고하자.[1]

API 확장

api 확장 방식에는 API Aggregation Layer, CRD가 있다.

경고!!

미완성된 글입니다!!
추가 작성해야 하는 글입니다!!!

관련 문서

이름 noteType created
API 접근 제어 우회 knowledge 2025-01-13
Authentication knowledge 2025-01-13
Authorization knowledge 2025-01-19
Prometheus-Adapter knowledge 2025-03-04
kube-apiserver knowledge 2025-03-12
쿠버네티스 API 구조 knowledge 2025-03-19
6W - PKI 구조, CSR 리소스를 통한 api 서버 조회 published 2025-03-15
6W - api 구조와 보안 1 - 인증 published 2025-03-15
6W - EKS api 서버 접근 보안 published 2025-03-16
E-api 서버 감사 topic/explain 2025-01-21

참고


  1. https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#api-overview ↩︎